package com.taoym.voucher.common.utils;

import com.taoym.voucher.common.response.ResponseStatusCode;
import io.jsonwebtoken.*;
import org.springframework.util.ObjectUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * @author: taoym
 * @date: 2021/5/8 11:46
 * @desc: jwt工具类
 */
public class JwtTokenUtils {

    /**
     * 私钥
     */
    private static final String KEY;
    /**
     * token有效时间 30分钟
     */
    private static final long TOKEN_TTL = 30 * 60 * 1000;
    /**
     * refreshToken的有效时间
     */
    private static final long REFRESH_TOKEN = 60 * 60 * 1000;

    static {
        String profile = System.getProperty("user.dir") + "\\common\\src\\main\\resources\\profile.properties";
        Properties properties = new Properties();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(profile));
            properties.load(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        KEY = properties.getProperty("JwtTokenUtils.key");
    }

    public static String createJwtToken(Map<String, Object> claims, boolean refreshToken) {

        claims.put("created", new Date());
        // 创建jwtBuilder
        JwtBuilder jwtBuilder = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(generateExpirationDate(refreshToken ? REFRESH_TOKEN : TOKEN_TTL))
                .signWith(SignatureAlgorithm.HS256, KEY.getBytes());
        return jwtBuilder.compact();
    }

    /**
     * @coder taoym
     * @datetime 2021/9/26 16:46
     * @desc token续签
     */
    public static String renewalToken(Claims claims) {
        claims.setExpiration(generateExpirationDate(TOKEN_TTL));
        return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, KEY.getBytes()).compact();
    }

    /**
     * @coder taoym
     * @datetime 2021/7/9 22:53
     * @desc 判断token是否过期，过期则抛出过期异常
     */
    public static boolean validateTokenIsExpired(String token, boolean isRefreshToken) {

        try {
            Jwts.parser().setSigningKey(KEY.getBytes()).parseClaimsJws(token);
        } catch (ExpiredJwtException e) {
            throw new ExceptionCore(isRefreshToken ? ResponseStatusCode.REFRESH_TOKEN_IS_EXPIRED : ResponseStatusCode.TOKEN_IS_EXPIRED);
        } catch (MalformedJwtException | SignatureException e) {
            throw new ExceptionCore(ResponseStatusCode.TOKEN_ANALYSIS_FAIL);
        }
        return false;
    }

    /**
     * 解析token
     */
    public static Claims getClaimsFromToken(String token) {
        try {
            return Jwts.parser().setSigningKey(KEY.getBytes()).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            return e.getClaims();
        } catch (MalformedJwtException | SignatureException e) {
            throw new ExceptionCore(ResponseStatusCode.TOKEN_ANALYSIS_FAIL);
        }
    }

    /**
     * 生成token的过期时间
     */
    private static Date generateExpirationDate(long ttl) {
        return new Date(System.currentTimeMillis() + ttl);
    }
}
